Package weasel.compiler

Source Code of weasel.compiler.WeaselTokenParser

package weasel.compiler;

import java.io.EOFException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.ListIterator;
import java.util.Map.Entry;

import powercraftCombi.Test;
import weasel.compiler.WeaselOperator.Properties;
import weasel.compiler.keywords.WeaselKeyWord;
import weasel.interpreter.WeaselModifier;

public class WeaselTokenParser {

  private String source;
  private int pos;
  private int line;
  private boolean isEOFOk=true;
  private List<WeaselToken> firstTokens = new ArrayList<WeaselToken>();
 
  public WeaselTokenParser(String source){
    this.source = source;
    pos = 0;
    line = 1;
  }
 
  public void setNextToken(WeaselToken token){
    firstTokens.add(0, token);
  }
 
  public WeaselToken getNextToken() throws WeaselCompilerException{
    if(!firstTokens.isEmpty())
      return firstTokens.remove(0);
    isEOFOk=true;
    try{
      char c = skipWhiteSpace();
      isEOFOk = false;
//Keyword&Ident-Parsing
      if(isAlphabetical(c)){
        String ident="";
        while(isAlphabetical(c)||isDigit(c)){
          ident += c;
          c = readNextChar();
        }
        readPrevChar();
        if(ident.equals("true")){
          return new WeaselToken(WeaselTokenType.BOOL, line, true);
        }else if(ident.equals("false")){
          return new WeaselToken(WeaselTokenType.BOOL, line, false);
        }else if(ident.equals("null")){
          return new WeaselToken(WeaselTokenType.NULL, line, null);
        }
        int modifier = WeaselModifier.getModifier(ident);
        if(modifier!=0){
          return new WeaselToken(WeaselTokenType.MODIFIER, line, modifier);
        }
        WeaselKeyWord wkw = WeaselKeyWord.getWeaselKeyWord(ident);
        if(wkw!=null){
          return new WeaselToken(WeaselTokenType.KEYWORD, line, wkw);
        }
        return new WeaselToken(WeaselTokenType.IDENT, line, ident);
      }
//Number-Parsing
      if(isDigit(c) || c=='.'){
        boolean isDot = c=='.';
        int num=0;
        if(c=='0'){
          c = readNextChar();
//HexInteger-Parsing
          if(c=='x'){
            c = readNextChar();
            if(!(isDigit(c) || (c>='a' && c<='f') || (c>='A' && c<='F')))
              throw new WeaselCompilerException(line, "Expect hex but got "+c);
            while(true) {
              if(isDigit(c)){
                num<<=4;
                num+=c-'0';
              }else if(c>='a' && c<='f'){
                num<<=4;
                num+=c-'a'+10;
              }else if(c>='A' && c<='F'){
                num<<=4;
                num+=c-'A'+10;
              }else if(isAlphabetical(c)){
                throw new WeaselCompilerException(line, "Expect hex but got "+c);
              }else{
                break;
              }
              c = readNextChar();
            }
            readPrevChar();
            return new WeaselToken(WeaselTokenType.INTEGER, line, num);
//BinaryInteger-Parsing
          }else if(c=='b'){
            c = readNextChar();
            if(!(c=='0' || c=='1'))
              throw new WeaselCompilerException(line, "Expect bit but got "+c);
            while(true) {
              if(c=='0' || c=='1'){
                num<<=1;
                if(c=='1')
                  num++;
              }else if(isDigit(c)||isAlphabetical(c)){
                throw new WeaselCompilerException(line, "Expect bit but got "+c);
              }else{
                break;
              }
              c = readNextChar();
            }
            readPrevChar();
            return new WeaselToken(WeaselTokenType.INTEGER, line, num);
          }
        }
//Integer-Parsing
        while(isDigit(c)){
          num *= 10;
          num += c-'0';
          c = readNextChar();
        }
        if(c=='l' || c=='L')
          return new WeaselToken(WeaselTokenType.LONG, line, num);
        if(c=='d' || c=='D')
          return new WeaselToken(WeaselTokenType.DOUBLE, line, num);
        if(c=='f' || c=='F')
          return new WeaselToken(WeaselTokenType.FLOAT, line, num);
//FloatingPoint-Parsing
        if(c=='.'){
          c = readNextChar();
          if(!isDot || isDigit(c)){
            int d=0;
            int i=1;
            while(isDigit(c)){
              d *= 10;
              d += c-'0';
              i *= 10;
              c = readNextChar();
            }
            if(c=='f' || c=='F')
              return new WeaselToken(WeaselTokenType.FLOAT, line, num);
            if(!(c=='d'||c=='D'))
              c = readPrevChar();
            return new WeaselToken(WeaselTokenType.DOUBLE, line, num+(double)d/i);
          }
          readPrevChar();
          c='.';
        }else if(isAlphabetical(c)){
          throw new WeaselCompilerException(line, "Expect number but got "+c);
        }else{
          readPrevChar();
          return new WeaselToken(WeaselTokenType.INTEGER, line, num);
        }
      }
//String-Parsing
      if(c=='"'){
        c = readNextChar();
        String s="";
        while(c!='"'){
          if(c=='\\'){
            c = readNextChar();
            switch(c){
            case 'n':
              s+='\n';
              break;
            case 't':
              s+='\t';
              break;
            case '"':
              s+='"';
              break;
            case '\\':
              s+='\\';
              break;
            default:
              throw new WeaselCompilerException(line, "Expect \\n, \\t, \\\" or \\\\");
            }
          }else{
            s += c;
          }
          c = readNextChar();
        }
        return new WeaselToken(WeaselTokenType.STRING, line, s);
      }
//Char-Parsing
      if(c=='\''){
        c = readNextChar();
        String s="";
        while(c!='\''){
          if(c=='\\'){
            c = readNextChar();
            switch(c){
            case 'n':
              s+='\n';
              break;
            case 't':
              s+='\t';
              break;
            case '\'':
              s+='\'';
              break;
            case '\\':
              s+='\\';
              break;
            default:
              throw new WeaselCompilerException(line, "Expect \\n, \\t, \\\' or \\\\");
            }
          }else{
            s += c;
          }
          c = readNextChar();
        }
        return new WeaselToken(WeaselTokenType.CHAR, line, s);
      }
      isEOFOk = true;
      WeaselTokenType wtt = WeaselTokenType.getTokenTypeFor(""+c, false);
      if(wtt!=null){
        return new WeaselToken(wtt, line);
      }
      Properties lastFullEqual = null;
      boolean again = true;
      String s="";
      int back=0;
      isEOFOk = false;
      while(again){
        again = false;
        s+=c;
        for(Entry<String, Properties> wo:WeaselOperator.operators.entrySet()){
          if(wo.getKey().equals(s)){
            lastFullEqual = wo.getValue();
            back = 0;
          }else if(wo.getKey().startsWith(s)){
            again = true;
          }
        }
        back++;
        c=readNextChar();
      }
      isEOFOk = true;
      while(back>0){
        back--;
        c = readPrevChar();
      }
      if(lastFullEqual!=null){
        return new WeaselToken(WeaselTokenType.OPERATOR, line, lastFullEqual);
      }
      wtt = WeaselTokenType.getTokenTypeFor(""+c, true);
      if(wtt!=null){
        return new WeaselToken(wtt, line);
      }
      throw new WeaselCompilerException(line, "Unexpected char "+c);
    }catch(EOFException e){
      if(isEOFOk){
        return new WeaselToken(WeaselTokenType.NONE, line);
      }
      throw new WeaselCompilerException(line, "Unexpect end of file");
    }
  }
 
  private boolean isSpace(char c){
    return c==' '||c=='\t'||c=='\r'||c=='\n';
  }
 
  private boolean isDigit(char c){
    return c>='0' && c<='9';
  }
 
  private boolean isAlphabetical(char c){
    return (c>='a' && c<='z') || (c>='A' && c<='Z') || c=='_';
  }
 
  private char skipWhiteSpace() throws EOFException{
    int length = source.length();
    if(length<=pos){
      throw new EOFException();
    }
    char c = source.charAt(pos);
    pos++;
    while(isSpace(c)){
      if(c=='\n')
        line++;
      if(length<=pos){
        throw new EOFException();
      }
      c = source.charAt(pos);
      pos++;
    }
    if(c=='/'){
      c = readNextChar();
      if(c=='/'){
        while(readNextChar()!='\n');
        return skipWhiteSpace();
      }else if(c=='*'){
        isEOFOk=false;
        while(true){
          c=readNextChar();
          if(c=='*'){
            c=readNextChar();
            if(c=='/')
              break;
          }
        }
        isEOFOk=true;
        return skipWhiteSpace();
      }else{
        c = readPrevChar();
      }
    }
    return c;
  }
 
  private char readNextChar() throws EOFException{
    int length = source.length();
    if(length<=pos){
      throw new EOFException();
    }
    char c = source.charAt(pos);
    pos++;
    if(c=='\n')
      line++;
    return c;
  }
 
  private char readPrevChar() throws EOFException{
    pos--;
    if(pos<=0){
      throw new EOFException();
    }
    char c = source.charAt(pos);
    if(c=='\n')
      line--;
    pos--;
    c = source.charAt(pos);
    pos++;
    return c;
  }

  public int getLine() {
    return line;
  }

  public ListIterator<WeaselToken> listIterator() {
   
    return new ListIterator<WeaselToken>(){

      private List<WeaselToken> read = new ArrayList<WeaselToken>();
      private int index=0;
     
      @Override
      public void add(WeaselToken e) {
        setNextToken(e);
      }

      @Override
      public boolean hasNext() {
        return true;
      }

      @Override
      public boolean hasPrevious() {
        return !read.isEmpty();
      }

      @Override
      public WeaselToken next() {
        if(read.size()>index){
          return read.get(index++);
        }
        WeaselToken wt = null;
        try {
          wt = getNextToken();
        } catch (WeaselCompilerException e) {
          e.printStackTrace();
        }
        read.add(wt);
        index++;
        return wt;
      }

      @Override
      public int nextIndex() {
        return index;
      }

      @Override
      public WeaselToken previous() {
        if(index==0)
          return null;
        return read.get(--index);
      }

      @Override
      public int previousIndex() {
        return index-1;
      }

      @Override
      public void remove() {}

      @Override
      public void set(WeaselToken e) {}
    };
  }
 
}
TOP

Related Classes of weasel.compiler.WeaselTokenParser

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.